#ifndef _AUTOMATA_H_
#define	_AUTOMATA_H_

#define BUF_SIZE 255

#include <stdio.h>
#include "longInt.h"

/******************************************************************************/
/**                              Data Structures                             **/
/******************************************************************************/


typedef struct t_input{
    int dim;
    char ** chains;
}t_input;

typedef struct t_int_vector{
    int dim;
    int * vec;
    int maxDim;
}t_int_vector;

typedef struct t_matrix{
    int dimFils;
    int fils;
    int cols;
    int ** data; 
}t_matrix;

typedef struct t_table{
    char * alphabet; //null terminated string, where each char is an alphabet's symbol
    int originalDim; //How many states where declared at first, from the file
    t_longInt_vector states;
    int iniState;
    t_longInt_vector finalStates;
    t_matrix transitions;
    t_input input;
    int originalFinalDim; //How many states where declared as final, at first
}t_table;


/******************************************************************************/
/**                              Prototypes                                  **/
/******************************************************************************/

/*
*   Builds transition matrix
*/
t_matrix buildMatrix(int fil, int col);

/*
*   Writes .out file containing Minimal DFA
*/
void writeFile(FILE * f, t_table * t);

/*
*   Parses input file completing neede structures and matrix
*/
t_table parseFile(FILE * f);

/*
*   Retrieves symbol index from alphabet
*/
int getSymIndex(char * alphabet, char symbol);

/*
*   Retrieves state index from state's vector
*/
int getStateIndex(t_table * t, t_longInt l);

/*
*   Completes a matrix slot with required transition. If slot already filled,
*   creates a new state and replaces slot with new state index.
*/
void addTransition(t_table * t, int from_state, int symbol_index, int to_state);

/*
*   Reads a line from a file until '\n', returns its length
*/
int getline(char * line, int max, FILE * f);

/*
*   Removes lambda transitions in matrix
*/
void removeLambdaTrans(t_table * t);

/*
*   Checks whether state's lambda closure contains any of the originally
*   declared final states, in which case adds state to the final states
*/
void checkFinalInClosure(t_table * t, t_longInt closure, int state);

/*
*   Revisits each state in state's vector to check whether it should also be
*   in final sates vector, due to the possible addition of a new final state
*   during the execution of 'checkFinalInClosure'
*/
void recheckFinalStates(t_table * t);

/*
*   Returns in 'closure' the lambda closure of 'state'
*/
void setLambdaClosure(int state, t_table * t, t_longInt closure, t_longInt checked);

/*
*   Checks if 'state' has already been marked as seen in 'l'. This way, infinite
*   loops are avoided during lambda closure calculation
*/
int alreadySeen(int state, int originalDim, t_longInt l);

/*
*   Determine if state of index 'state' is final
*/
int isFinalStInd(t_table *t, int state);


#endif
